home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-06-24 | 27.6 KB | 784 lines | [TEXT/pdos] |
- *******************************************************************************
- *
- * RoundRect Window
- *
- * (C) Copyright Apple Computer, Inc. 1988-1990
- * All rights reserved.
- *
- * Developer Technical Support Apple II Sample Code
- *
- * by Keith Rollin
- *
- * This file contains the definition procedure (defProc) for a custom window.
- * This window acts like a fairly normal, but limited, window, and has the
- * following features:
- *
- * - The corners are curved. The radius of the corners can be specified.
- * - It always has a title bar, which always has a solid background color
- * and title in it. The titlebar redraws itself in response to being
- * activated and deactivated.
- * - A GoAway box can optionally be included in the title bar. The zoom
- * box is not drawn or supported.
- * - There are no infobars or frame controls (like scrollbars).
- * - A color table can be provided, or a default color table can be used.
- * - The window can be dragged and grown.
- * - TaskMaster is supported.
- *
- *******************************************************************************
-
- EJECT
- *******************************************************************************
- *
- RRectDefProcData data
- *
- * Description: Equates and variables used by the RoundRect Window defProc.
- *
- *
- *******************************************************************************
-
- ; stack/direct page frame. These equates are used to access information that
- ; is passed to the window DefProc on the stack.
-
-
- DefineStack
-
- OrigD word ; saved Direct Page register
- OrigB byte ; saved Data Bank register
- work long ; a LONG of workspace
- workRgn long ; a LONG of workspace
- returnAddr block 3 ; RTL address
- param long ; operation specific parameter
- theWindow long ; This is NOT a pointer to the window.
- * ; This is a pointer to a window record.
- * ; This means that it points to
- * ; owNext, not the grafPort part of
- * ; a window record!!
- operation word ; operation to perform
- windGlobals long ; pointer to handy values
- result long ; place to store operation result
-
- ;
- ; Window Globals table
- ;
- lineW equ 0 ; width of vertical lines
- titleHeight equ lineW+2 ; Height of standard title bar
- titleYPos equ titleHeight+2 ; Y offset for title in std. titlebar
- closeHeight equ titleYPos+2 ; height of close icon.
- closeWidth equ closeHeight+2 ; width of close icon.
- defWindClr equ closeWidth+2 ; pointer to default color table
- windIconFont equ defWindClr+4 ; handle to current window icon font
- screenMode equ windIconFont+4 ; TRUE if 640 mode, FALSE if 320
- pattern equ screenMode+2 ; Temporary pattern buffer
- callerDPage equ pattern+32 ; DP of last caller to TaskMaster
- callerDataB equ callerDPage+2 ; DBR of last caller to TaskMaster
-
- ;
- ; NewWindow Parameter list
- ;
- DSect 0
- wParamID word ; should be zero for custom windows
- wMe long ; address of customProc
- wFrameBits word ; flags that determine window type
- wPosition block 8 ; used as portRect for contents
- wPlane long ; window Plane
- wStorage long ; storage for the window record
- ; These 2 are copied in one pass. Keep together and in this order.
- wRefCon long ; refCon
- wContDraw long ; routine that draw the contents
- ; Everything past here is copied after the wFrame field of the Window Record.
- wCustom block 0 ; start of custom information section
- wTitle long ; pointer to window's title
- wColorTable long ; pointer to color table
- wRV word ; vertical radius of corners
- wRH word ; horizontal radius of corners
- wEnd block 0
-
- ;
- ; My extensions for this custom window
- ;
- DSect windSize
- xowTitle long ; pointer to window's title
- xowColorPtr long ; pointer to our color table (if any)
- xowRV word ; vertical radius of corners
- xowRH word ; horizontal radius of corners
- xowEnd block 0
-
- ;
- ; Position of the GoAway box
- ;
- GAX equ 10
- GAY equ 2
-
- ;
- ; Scratch areas
- ;
- contRect ds 8
- strucRect ds 8
- pRect ds 8
-
- end
-
-
- EJECT
- *******************************************************************************
- *
- RRectDefProc start
- *
- * Description: Main Procedure for the RoundRect custom window definition.
- * This routine creates a suitable environment for us (saves
- * the old Direct Page and Data Bank registers and makes us
- * some new ones), calls the appropriate routine based on
- * the value of 'operation', and returns to the Window
- * Manager with the Carry bit and Y register set correctly.
- *
- *
- * Inputs:
- * On entry, the stack contains the following values:
- *
- * -------- previous contents --------
- * LONG result space for result
- * LONG windGlobals pointer to WMgr globals
- * WORD operation operation number to be performed
- * LONG theWindow ptr to window's record
- * LONG param additional parameter for some ops.
- * 3 Bytes RTL Address
- * <------------ Stack Pointer
- *
- * Outputs: Carry = clear if no error
- * Carry = set if error, and Y has error number.
- *
- * External Refs:
- * Import rrDraw
- * Import rrHit
- * Import rrCalcRgns
- * Import rrNew
- * Import rrDispose
- * Import rrGetDrag
- * Import rrGrowFrame
- * Import rrRecSize
- * Import rrPosition
- * Import rrBehind
- * Import rrCallDefProc
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using RRectDefProcData
- wMaxTask equ 10
-
- ; The first thing we do is get a little Direct Page space by using the stack.
- ; First, push on some scratch space onto the stack, then save the old values
- ; of the Data Bank Register and the Direct Page Register. Set the Data Bank
- ; Register to the same value as the Program Bank Register, and then transfer
- ; the Stack Pointer to the Direct Page Register. This gives us a stack and
- ; Direct Page that looks like this:
- ;
- ; Direct Page location SIZE What it is
- ; 25 LONG result
- ; 21 LONG windGlobals
- ; 19 WORD operation
- ; 15 LONG theWindow
- ; 11 LONG param
- ; 8 3 Bytes RTL Address
- ; 4 LONG workspace
- ; 3 BYTE old Data Bank Register
- ; 1 WORD old Direct Page Register
- ; <--- stack pointer
-
- pha ; Push on 8 bytes of workspace.
- pha
- pha
- pha
-
- phb ; Save the data bank register
- phd ; Save the direct page register
-
- ; Set the Data Bank register to the Program Bank register. This allows short
- ; (2 byte) addressing, as opposed to the 3 byte addressing we would have had
- ; to use if the Data Bank register were set to some unknown value.
-
- phk ; Set up my own DBR
- plb
-
- ; Set the direct page to the stack. This lets us use some of the values passed
- ; to us as 'zero-page' pointers (like theWindow).
-
- tsc ; Set up my own Direct Page
- tcd
-
- ; Zero out 'result' as default.
-
- stz <result ; zero this out to start with
- stz <result+2
-
- ; Find out which operation to perform, check its range, and, if it is OK,
- ; convert it to an index into a jump table. Execute the routine.
-
- lda <operation
- cmp #wMaxTask+1
- bcs OutOfRange
-
- asl a
- tax
- jsr (opTable,x)
-
- ; The operation has been carried out. Strip the parameters off of the stack
- ; and move the return address up, making sure to leave the 'result'. Gotta be
- ; careful to preserve the carry flag here!!!
-
- OutOfRange lda <returnAddr ; move the return address up
- sta <result-3
- lda <returnAddr+1
- sta <result-2
-
- tsc ; get the stack ptr so we can change it
-
- pld ; restore the DP and DBR
- plb
-
- php ; save the state of the carry
- clc ; fudge the stack pointer
- adc #result-4
- plp ; restore the carry state
- tcs ; point the stack pointer to the return
- * ; address we moved up
-
- rtl ; back to the window manager
-
- opTable dc i2'rrDraw' ; Draw the specified part
- dc i2'rrHit' ; determine where we hit
- dc i2'rrCalcRgns' ; Calculate Struc and Content Regions
- dc i2'rrNew' ; Perform initialization
- dc i2'rrDispose' ; Close window
- dc i2'rrGetDrag' ; Dragging to be done
- dc i2'rrGrowFrame' ; Grow the frame
- dc i2'rrRecSize' ; Return our window record size
- dc i2'rrPosition' ; Return window pos/size
- dc i2'rrBehind' ; Return plane placement
- dc i2'rrCallDefProc' ; Perform special stuff
-
- end
-
- EJECT
- *******************************************************************************
- *
- rrDraw start
- *
- * Description: Draw the specified part of the window.
- *
- * We draw the window frame (part $0000) in the following way:
- *
- * 1. Save various QuickDraw states that we will be changing.
- * 2. Set the pen to normal.
- * 3. Get the rectangle of our structure region.
- * 4. Get a pointer to the color table we'll be using.
- * 5. Set the color of the title bar (background). This changes
- * depending on whether the window is active or not.
- * 6. Draw the title bar with PaintRect.
- * 7. Set the color to the outline color.
- * 8. Draw the main part of the frame with FrameRRect.
- * 9. Draw the line that divides the title bar from the content region.
- * 10. Calculate and position the pen for the string title.
- * 11. Set the color for the title. Again, this changes depending on
- * whether the window is active or not.
- * 12. If the window is active, call the standalone routine that draws
- * the close box (part $0001).
- * 13. Restore the QuickDraw state we saved and return.
- *
- *
- * Inputs: param = specification of part to draw:
- *
- * 0 = draw the entire window
- * 1 = draw the go-away region
- * 2 = draw the zoom region
- * 3 = draw the info bar
- *
- * If the high bit of param is set, then draw the item in
- * its highlighted state. Note: to determine whether to draw
- * a window titlebar in its active or inactive state, look
- * at the fHilite flag in the window record.
- *
- * Outputs: result = zero
- * carry = clear
- *
- * External Refs: NONE
- *
- * Entry Points:
- * entry drawFrame ; called by rrSetxxxx routines when a
- * ; field is changed.
- *
- *******************************************************************************
- using RRectDefProcData
-
- lda <param ; find out which part to draw
- asl a ; turn into an index into a jump table
- tax
- jsr (partToDraw,x)
-
- clc
- rts
-
- partToDraw dc i2'drawFrame'
- dc i2'drawGoAway'
- dc i2'drawZoomBox'
- dc i2'drawInfoBar'
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Draws the entire frame of a window. This includes the go-away box and any
- ; other parts of the frame that you may implement (like a zoom box, an
- ; infobar, scrollbars, grow box, etc.
- ;
- drawFrame entry
- pha ; save the text mode (on the stack!)
- _GetTextMode
-
- pha
- _GetPenMode
-
- pha ; and the color (on the stack!)
- _GetForeColor
-
- _PenNormal
-
- jsr GetStrucRect
-
- jsr SetColorTable ; put ptr to a color table into 'work'
-
- ;
- ; Now draw the background of the window. Set the color to the backbround color
- ; in the color table, then do a PaintRect to draw it all.
- ;
- jsr SetBGColor
-
- ldy #6 ;Make a local rectangle that
- aa lda strucRect,y ;encompasses the title bar.
- sta pRect,y
- dey
- dey
- bpl aa
- ldy #titleHeight
- clc
- adc [<windGlobals],y
- dec a
- sta pRect+4
- inc pRect
-
- pha ;Make a rectangular region the
- pha ;same size as this rectangle.
- _NewRgn
- lda 1,s
- sta <workRgn
- lda 3,s
- sta <workRgn+2
- pea pRect|-16
- pea pRect
- _RectRgn
-
- stz offset
- stz offset+2
- PushLong #offset
- _LocalToGlobal
- pei <workRgn+2
- pei <workRgn
- lda offset+2
- pha
- lda offset
- pha
- _OffsetRgn
-
- ldy #owStrucRgn+2 ; get the handle from the window record
- lda [<theWindow],y
- pha
- dey
- dey
- lda [<theWindow],y
- pha
- pei <workRgn+2
- pei <workRgn
- pei <workRgn+2
- pei <workRgn
- _SectRgn
-
- stz offset
- stz offset+2
- PushLong #offset
- _GlobalToLocal
- pei <workRgn+2
- pei <workRgn
- lda offset+2
- pha
- lda offset
- pha
- _OffsetRgn
-
- pei <workRgn+2
- pei <workRgn
- pea 2
- pea 0
- _InsetRgn
-
- pei <workRgn+2
- pei <workRgn
- _PaintRgn
-
- ;
- ; Draw the frame. Set the outline color and the Pen Width, and use
- ; 'strucRect' to call FrameRRect.
- ;
-
- ldy #oframeColor ; set the outline color
- lda [<work],y ; in bits 7-4
- lsr a
- lsr a
- lsr a
- lsr a
- and #%00001111
- pha
- _SetSolidPenPat
-
- ldy #lineW ; now set up the pen size by using the
- lda [<windGlobals],y ; pen width value the Window Manager
- pha ; passes to us in the Globals section.
- PushWord #1 ; hardcode the height to 1
- _SetPenSize
-
- PushLong #strucRect ; now draw the entire frame
- ldy #xowRH ; these are the radii of the corners
- lda [<theWindow],y
- pha
- ldy #xowRV
- lda [<theWindow],y
- pha
- _FrameRRect
-
- lda strucRect ; calculate the VPos of the dividing
- ldy #titleHeight ; line.
- clc
- adc [<windGlobals],y
- dec a
-
- ldx strucRect+6 ; push on first X/Y coordinate of a
- dex ; moveTo/lineTo sequence
- dex
- phx
- pha
-
- ldx strucRect+2 ; the other X/Y coordinate
- phx
- pha
-
- _MoveTo ; draw the dividing line
- _LineTo
-
- ; Position and draw the title. Use 'oTitleColor' in the color table.
-
- jsr GetStringXPos
-
- PushWord XPos ; Next position to draw the title
- ldy #titleYPos ; let the window manager tell us its
- PushWord [<windGlobals],y ; vertical position.
- _Moveto
-
- PushWord #modeForeCopy ; set mode to our liking
- _SetTextMode
-
- jsr SetTitleColor ; set up colors accordingly
-
- PushLong TitlePtr ; draw the title
- _DrawString
-
- jsr WindowActive ; Is the window active? If so
- beq noGoAway ; don't grow goAway box
-
- ldy #owFrame ; does this window have a close
- lda [<theWindow],y ; box?
- and #fClose
- beq noGoAway ; no so don't draw one.
-
- jsr drawGoAway
-
- noGoAway ANOP
- _SetForeColor ; restore the color and the mode
- _SetPenMode
- _SetTextMode
-
- rts
-
- offset ds 4
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Draw JUST the go-away box in the frame. This will ususally be called when
- ; TrakGoAway needs to (un)hilite it, but it could really be called at any
- ; time.
-
- drawGoAway ANOP
- jsr SetColorTable ; get a pointer to color table
-
- pha ; save the text mode (on the stack!)
- _GetTextMode
-
- pha ; and the color (on the stack!)
- _GetForeColor
-
- pha ; and the color (on the stack!)
- _GetBackColor
-
- PushWord #modeCopy ; set mode to our liking
- _SetTextMode
-
- ldy #otitleColor ; set the text color
- lda [<work],y
- and #%00001111
- pha
- _SetForeColor
-
- ldy #otBarColor ; set the background
- lda [<work],y
- and #%00001111
- pha
- _SetBackColor
-
- pha ; save the current font so that we
- pha ; can switch to the Window Manager
- _GetFont ; icon font.
- PullLong OldFont
-
- ldy #windIconFont+2 ; Get the Window icons from the
- PushWord [<windGlobals],y ; window globals area
- dey
- dey
- PushWord [<windGlobals],y
- _SetFont
-
- PushWord #GAX ; X position for goaway
- PushWord #GAY ; Y ditto
- _MoveTo
-
- lda <param+2 ; how are we to draw this?
- bmi DrawHilited
-
- PushWord #0 ; draw a normal go-away box
- bra DrawIt
- DrawHilited PushWord #1 ; draw a hilited go-away box
- DrawIt _DrawChar
-
- PushLong OldFont ; put the old font back
- _SetFont
-
- _SetBackColor ; restore the mode and color
- _SetForeColor ; restore the mode and color
- _SetTextMode
-
- rts
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; These aren't implemented.
-
- drawZoomBox ANOP
- drawInfoBar ANOP
- rts
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Utility routines for DrawFrame
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Check the window record to see if there is a pointer to a
- ; color table there. If there is one, put it into 'work' for
- ; later use. If there isn't one, use the default provided us
- ; by the Window Manager in WindGlobals.
- ;
-
- SetColorTable ANOP
- ldy #xowColorPtr ; set what is pointed to in the
- lda [<theWindow],y ; window record. Store it into
- sta <work ; 'work' assuming that it is not
- iny ; zero.
- iny
- lda [<theWindow],y
- sta <work+2
- ora <work ; is it really zero?
- bne done ; no, so use it.
-
- ldy #defWindClr ; yes, it is zero. Use the defaults.
- lda [<windGlobals],y
- sta <work
- iny
- iny
- lda [<windGlobals],y
- sta <work+2
- done ANOP
- rts
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Do some math to determine where the title string will go. We use
- ; the formula: (midpoint of the window) - (half the length of the string)
- ;
- ; (left + (right - left) / 2)) - (StringWidth) / 2
- ;
- ; which reduces to:
- ;
- ; (left + right - StringWidth) / 2
- ;
-
- GetStringXPos ANOP
- ldy #xowTitle+2 ; get the offset in the record to the
- lda [<theWindow],y ; title
- sta TitlePtr+2
- dey
- dey
- lda [<theWindow],y
- sta TitlePtr
-
- pha ; find out how long it is to center it
- PushLong TitlePtr
- _StringWidth
- PullWord XPos ; save it here for a little bit
- ;
- ; now find the left edge of the string by using the equation:
- ; (windLeft+windRight-strLen)/2
- ;
- ldy #oport+oportRect+6 ; get the right edge of the window
- lda [<theWindow],y
- dey
- dey
- dey
- dey
- clc
- adc [<theWindow],y ; add the right edge
- sec
- sbc XPos ; subtract the string's width
- lsr a ; divide it all by two
- sta XPos ; save the left edge starting position
- rts
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Get the boundsRect of the StrucRgn in the window record. This allows us
- ; to do a simple FrameRRect(portRect), which is a lot faster for drawing
- ; the frame than FrameRgn(strucRgn).
-
- GetStrucRect Entry ; also called from myDragRoutine
- ldy #owStrucRgn ; get the handle from the window record
- lda [<theWindow],y
- sta <work
- iny
- iny
- lda [<theWindow],y
- sta <work+2
-
- ldy #2 ; now dereference into a pointer
- lda [<work],y
- tax
- lda [<work]
- sta <work
- stx <work+2
-
- ldy #2+6 ; copy the rgnBBox into pRect
- ldx #6
- loop ANOP
- lda [<work],y
- sta strucRect,x
- dey
- dey
- dex
- dex
- bpl loop
-
- PushLong #strucRect
- _GlobalToLocal
-
- PushLong #strucRect+4
- _GlobalToLocal
- rts
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Find the state of the window (whether it's active or not), and set
- ; the BackGround color of the Title bar accordingly. These colors are
- ; obtained from the color table pointed to by 'work'.
-
- SetBGColor ANOP
- jsr WindowActive ; drawing an inactive window?
- beq Inact1 ; yes, set the right color
-
- ldy #otBarColor ; set the background color
- lda [<work],y
- and #%00001111 ; in bits 3-0
- pha
- bra SetIt1
-
- Inact1 ANOP
- ldy #otitleColor ; set the background color
- lda [<work],y
- xba ; in bits 11-8
- and #%00001111
- pha
-
- SetIt1 ANOP
- _SetSolidPenPat
- rts
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; We are about to draw the title in the title bar. This routine gets
- ; and sets the color for that based on the entry in the color table
- ; pointed to by 'work'.
-
- SetTitleColor ANOP
- jsr WindowActive ; is this an inactive window?
- beq Inact2 ; yes
-
- ldy #otitleColor ; set the text color
- lda [<work],y
- and #%00001111 ; in bits 3-0
- pha
- bra SetIt2
-
- Inact2 ANOP
- ldy #otitleColor ; set the text color
- lda [<work],y
- lsr a ; in bits 7-4
- lsr a
- lsr a
- lsr a
- and #%00001111
- pha
-
- SetIt2 ANOP
- _SetForeColor
- rts
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Short utility routine that returns z=1 if the window is active
- ; and z=0 if not.
- ;
-
- WindowActive ANOP
- ldy #owFrame
- lda [<theWindow],y
- and #fHilited ; return z=1 if active window
- rts
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Local Data Storage
- ;
-
- TitlePtr ds 4
- XPos ds 2
- OldFont ds 4 ; holds old font when we switch to
- * ; the Window Manager font
- end
-